Ansibleのcowsay出力を虹色に輝かせたい
初めに
Ansibleをご利用の多くの方はご存知かと思いますが、Ansibleは実行環境にcowsay
がインストールされている場合デフォルトでcowsay
による出力が行われるようになっており、非常に重要なツールの1つとなっております。
とはいえ通常cowsay
を利用したいものの、プロフェッショナルな環境であれば時にはそういったジョークめいた出力は許されず無効化しないといけないケースはあるかと思います。
https://docs.ansible.com/ansible/latest/reference_appendices/config.html
ANSIBLE_NOCOWS
Description If you have cowsay installed but want to avoid the ‘cows’ (why????), use this.
永続的に無効化するのであればcowsay
自体を削除してしまうのも1つの手ですが、一時的に無効化したい時のためにAnsibleにはそれを無効化するための専用のオプションが用意されています。
出力を抑えたいケースがあり得る一方で、いやそうではないもっと壮大な、たとえばドラゴンのようなキャラクターを出力してもらいたいケースもあるでしょう。
そういった場合に備えAnsibleではANSIBLE_COW_SELECTION
環境変数を指定することでcowsay
に対して-f
オプションを与えたように実行をすることができます。
% ANSIBLE_COW_SELECTION=dragon ansible-playbook playbook.yml ... __________________ < PLAY [localhost] > ------------------ \ / \ //\ \ |\___/| / \// \\ /0 0 \__ / // | \ \ / / \/_/ // | \ \ @_^_@'/ \/_ // | \ \ //_^_/ \/_ // | \ \ ( //) | \/// | \ \ ( / /) _|_ / ) // | \ _\ ( // /) '/,_ _ _/ ( ; -. | _ _\.-~ .-~~~^-. (( / / )) ,-{ _ `-.|.-~-. .~ `. (( // / )) '/\ / ~-. _ .-~ .-~^-. \ (( /// )) `. { } / \ \ (( / )) .----~-.\ \-' .~ \ `. \^-. ///.----..> \ _ -~ `. ^-` ^-_ ///-._ _ _ _ _ _ _}^ - - - - ~ ~-- ,.-~ /.-~
しかしながら自分の気持ちとしてはcowsay
は牛が出力されるから"cow"sayであり、違うキャラにより輝いてもらいジョーク度を高めるのは違うのではないかとものがあります。
cowsay
は牛のまま輝いてほしいということで、目立つならゲーミングカラー、つまり今回は虹色に輝いてもらいます。
利用ツール
cowsayの呼び出しを差し替える
Ansibleで実行されるcowsay
は以下のパスに設置されているファイルを実行する仕様となっております(上位の方が優先度が高い)。
https://github.com/ansible/ansible/blob/stable-2.14/lib/ansible/utils/display.py
b_COW_PATHS = ( b"/usr/bin/cowsay", b"/usr/games/cowsay", b"/usr/local/bin/cowsay", # BSD path for cowsay b"/opt/local/bin/cowsay", # MacPorts path for cowsay )
上記以外のパスにcowsay
が設置されている、もしくは一時的に別のパスに設置されているcowsay
を利用したい場合は環境変数ANSIBLE_COW_PATH
、もしくはansible.cfg
のcowpath
パラメータにそのパスを指定することで差し替えることができます。
ANSIBLE_COW_PATH
Description
Specify a custom cowsay path or swap in your cowsay implementation of choice
...
Key
cowpath.
今回は上記の仕様に則りAnsible側で読み込ませる先のパスに自作スクリプトを設置してそれを実行させます。
lolcatについて
lolcat
コマンドは出力を虹色に変化されるコマンドであり、今回はこれを利用して虹色に出力させます。
今回はAnsibleのオプションの使い勝手が変わらないように引数は全てcowsayに渡るように以下のようなファイルを/opt/local/bin/cowsay
を作成します。
#!/bin/bash # % which cowsay # /opt/homebrew/bin/cowsay `which cowsay` $@ | lolcat --force
lolcat
にはシンプルにパイプで文字列を渡すだけでそれをグラデーションカラーで出力してくれるツールとなります。
Ansible上のcowsayのカラーリングについて
Ansibleでは出力メッセージレベルごとに文字色をを設定できるパラメータが存在します。
コマンドを前述のものに差し替えた場合でもこの設定により色が潰されていないかを懸念していましたが、そもそも牛の出力されるバナー部分の色に対する設定はないようです。
呼び出し元を追ってみるとcowsay
経由での出力を行うbanner_cowsay()
メソッドには出力色を指定できるcolor
引数が存在しますが、呼び出し元を確認すると実態としてcolorに対する値の引き渡しは特に行われていないようです。
https://github.com/ansible/ansible/blob/stable-2.14/lib/ansible/utils/display.py
そのためlolcat
にそのままcowsay
の出力を渡せばいい感じに色がつくかなと思ったのですが、実際に試してみると色の変更が行われずターミナルのデフォルト文字色が利用されました。
着色部分を追ってみたところ、ANSIエスケープシーケンスを付与して着色が必要となるようです。
https://github.com/ansible/ansible/blob/stable-2.14/lib/ansible/utils/color.py.
lolcat
で--force
オプションをつけることでANSIエスケープシーケンスを付与する形で出力ができるようなので、今回はこちらで対応を行いました。
実行
通常通り実行するだけで先ほど設置したcowsay
スクリプト経由での出力が行われ、虹色の牛がメッセージを読み上げます。
残念ながら縦横幅的に当初イメージしたより少ない色幅になった気がします。
とはいえこの辺りは出力文字数による幅や、出力時の乱数的に視覚的にわかりやすい色の切り替わり部分であるかというのは影響しそうです。
Ansible経由でのcowsay
関連のオプションは通常通り渡るので望むのであればドラゴン等別のものを出力させることも可能です。
終わりに
今回はAnsibleのcowsayの実行原理を利用して虹色に輝かせてみました。
フォーマルな出力が求められることは当然ある一方、ジョークめいた出力が許される環境もあるかとあるのではないかと思います。
やりすぎない程度にジョークを詰めていくのは癒しにもなりますし実は大切なのではないかもしれません。
最終的な出力自体はcowsay
からの出力をまとめてAnsibleが受け取り、あくまで最終的にAnsibleが出力を行う関係と仕組み上ストリーミングな出力等できないといった制限がつきまとう点は注意しましょう。
実はlolcat
にはアニメーション出力が可能なオプションが存在しますが、今回は上記の仕様上断念する形になりました。
一応Ansibleの出力部分に思いっきり手を入れればできなくはなさそうなのでぜひ興味のある方はチャレンジしてみてください。